package com.mas.strategey;

import java.util.Map;

import com.mas.common.Consts;
import com.mas.resource.ResourceInfo;

/**
 * This class handle all the agent negotiation strategy 
 */
public abstract class Strategy 
{

	/**
	 * Private price list,
	 */
	protected Map<String, Double> privatePriceList; 
	
	/**
	 * For seller will be small positive number, for buyer small negative number
	 */
	protected double discountedFactor;
	
	/**
	 * Related to my privatePrice what is the factor price for selling/buying
	 */
	protected double pricingFactor;

	protected Proposal myLastProposal = null;

	public Strategy() {

	}

	/**
	 *Get last proposal and decide what response to send
	 */
	abstract public Consts.Response decide(Proposal proposal) ;
	
	abstract protected void updateDiscountedFactor();

	public Proposal buildNewProposal(Proposal otherAgentProposal) 
	{
		double newPrice;
		double privateValue;
		Proposal newPproposal;

		newPproposal = new Proposal();
		newPproposal.setResourceInfos(otherAgentProposal.getResourceInfos());
		privateValue = calcPrivateValue(otherAgentProposal.getResourceInfos()); 
		
		if (myLastProposal != null)
		{
			newPrice = newPrice(this.myLastProposal.getPrice(), otherAgentProposal.getPrice(),privateValue);
		}
		else // no last proposal, send my private value 
		{
			newPrice = privateValue * pricingFactor;
		}

		newPproposal.setPrice(newPrice);

		this.myLastProposal = newPproposal;
		updateDiscountedFactor();
		return newPproposal;
	}

	abstract protected double newPrice(double myLastProposalPrice, double otherAgentProposalPrice, double myPrivateValue);
	
	
	protected double calcPrivateValue(ResourceInfo[] resourceInfos) 
	{
		Double total = 0.0;
		String resourceName;
		Double myPrivatePrice;
		Double resourceRequired;

		for (int i = 0; i < resourceInfos.length; i++) {
			// get resource name and amount
			resourceName = resourceInfos[i].getResourceName();
			resourceRequired = resourceInfos[i].getRequiredUsage();

			// get my private price for that resource
			myPrivatePrice = privatePriceList.get(resourceName);

			total += (Double) resourceRequired * myPrivatePrice;
		}
		return total;
	}
}